package com.smart.community.region.controller;

import com.smart.community.commons.result.Result;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.exception.BusinessException;
import com.smart.community.feign.property.service.DataScopeFeign;
import com.smart.community.region.dto.ZoneSaveRequest;
import com.smart.community.region.dto.ZoneDrawingSaveDTO;
import com.smart.community.region.service.IZoneManagementService;
import com.smart.community.region.vo.ZoneManagementInitialDataVO;
import com.smart.community.region.vo.CommunityEntryStateVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

/**
 * 分区管理控制器
 * 
 * @author Wu.Liang
 * @date 2025-01-30
 */
@Tag(name = "分区管理", description = "分区管理相关接口")
@RestController
@RequestMapping("/region/zone-management")
@Validated
@Slf4j
public class ZoneManagementController {

    @Autowired
    private IZoneManagementService zoneManagementService;

    @Autowired
    private DataScopeFeign dataScopeFeign;

    /**
     * 获取分区管理页面初始数据
     * 
     * @param communityId 社区ID
     * @return 初始数据
     */
    @GetMapping("/initial-data/{communityId}")
    @Operation(summary = "获取分区管理初始数据", description = "获取分区管理页面所需的初始数据")
    @ApiLog(logTitle = "获取分区管理初始数据", logType = 1, moduleName = "分区管理", operationType = ApiLogOperationType.QUERY)
    public Result<ZoneManagementInitialDataVO> getInitialData(
            @Parameter(description = "社区ID") @PathVariable @NotNull Long communityId) throws Exception {
        log.info("获取分区管理初始数据，社区ID: {}", communityId);
        
        // 数据权限验证
        validateCommunityPermission(communityId);
        
        ZoneManagementInitialDataVO data = zoneManagementService.getInitialData(communityId);
        return Result.success(data);
    }

    /**
     * 判断社区进入状态
     * 
     * @param communityId 社区ID
     * @return 进入状态
     */
    @GetMapping("/entry-state/{communityId}")
    @Operation(summary = "判断社区进入状态", description = "判断社区是初次进入还是非初次进入分区管理")
    @ApiLog(logTitle = "判断社区进入状态", logType = 1, moduleName = "分区管理", operationType = ApiLogOperationType.QUERY)
    public Result<CommunityEntryStateVO> determineEntryState(
            @Parameter(description = "社区ID") @PathVariable @NotNull Long communityId) throws Exception {
        log.info("判断社区进入状态，社区ID: {}", communityId);
        
        // 数据权限验证
        validateCommunityPermission(communityId);
        
        CommunityEntryStateVO state = zoneManagementService.determineCommunityEntryState(communityId);
        return Result.success(state);
    }

    /**
     * 保存分区管理数据
     * 
     * @param request 保存请求
     * @return 保存结果
     */
    @PostMapping("/save")
    @Operation(summary = "保存分区管理数据", description = "保存分区管理的完整数据")
    @ApiLog(logTitle = "保存分区管理数据", logType = 2, moduleName = "分区管理", operationType = ApiLogOperationType.ADD)
    public Result<String> saveZoneData(
            @Parameter(description = "保存请求") @Valid @RequestBody ZoneSaveRequest request) throws Exception {
        log.info("保存分区管理数据，社区ID: {}", request.getCommunityId());
        
        // 数据权限验证
        validateCommunityPermission(request.getCommunityId());
        
        String result = zoneManagementService.saveZoneData(request);
        return Result.success(result);
    }

    /**
     * 保存绘图数据
     * 
     * @param request 绘图数据
     * @return 保存结果
     */
    @PostMapping("/drawing")
    @Operation(summary = "保存绘图数据", description = "保存分区绘图的完整数据")
    @ApiLog(logTitle = "保存绘图数据", logType = 2, moduleName = "分区管理", operationType = ApiLogOperationType.ADD)
    public Result<String> saveDrawingData(
            @Parameter(description = "绘图数据") @Valid @RequestBody ZoneDrawingSaveDTO request) throws Exception {
        log.info("保存绘图数据，社区ID: {}", request.getCommunityId());
        
        // 数据权限验证
        validateCommunityPermission(request.getCommunityId());
        
        String result = zoneManagementService.saveDrawingData(request);
        return Result.success(result);
    }

    /**
     * 更新绘图数据
     * 
     * @param id 绘图数据ID
     * @param request 绘图数据
     * @return 更新结果
     */
    @PutMapping("/drawing/{id}")
    @Operation(summary = "更新绘图数据", description = "更新分区绘图的完整数据")
    @ApiLog(logTitle = "更新绘图数据", logType = 3, moduleName = "分区管理", operationType = ApiLogOperationType.UPDATE)
    public Result<String> updateDrawingData(
            @Parameter(description = "绘图数据ID") @PathVariable @NotNull Long id,
            @Parameter(description = "绘图数据") @Valid @RequestBody ZoneDrawingSaveDTO request) throws Exception {
        log.info("更新绘图数据，ID: {}, 社区ID: {}", id, request.getCommunityId());
        
        // 数据权限验证
        validateCommunityPermission(request.getCommunityId());
        
        String result = zoneManagementService.updateDrawingData(id, request);
        return Result.success(result);
    }

    /**
     * 获取社区绘图数据
     * 
     * @param communityId 社区ID
     * @return 绘图数据
     */
    @GetMapping("/drawing/community/{communityId}")
    @Operation(summary = "获取社区绘图数据", description = "获取指定社区的绘图数据")
    @ApiLog(logTitle = "获取社区绘图数据", logType = 1, moduleName = "分区管理", operationType = ApiLogOperationType.QUERY)
    public Result<Object> getCommunityDrawingData(
            @Parameter(description = "社区ID") @PathVariable @NotNull Long communityId) throws Exception {
        log.info("获取社区绘图数据，社区ID: {}", communityId);
        
        // 数据权限验证
        validateCommunityPermission(communityId);
        
        Object data = zoneManagementService.getCommunityDrawingData(communityId);
        return Result.success(data);
    }

    /**
     * 数据权限验证
     * 
     * @param communityId 社区ID
     */
    private void validateCommunityPermission(Long communityId) throws Exception {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        log.debug("验证用户权限，用户ID: {}, 社区ID: {}", currentUserId, communityId);
        
        try {
            // 1. 检查超级管理员权限
            Boolean isSuperAdmin = dataScopeFeign.isUserSuperAdmin(currentUserId);
            if (Boolean.TRUE.equals(isSuperAdmin)) {
                log.debug("用户{}为超级管理员，拥有所有权限", currentUserId);
                return;
            }
            
            // 2. 验证社区权限
            Boolean hasCommunityPermission = dataScopeFeign.hasCommunityPermission(currentUserId, communityId);
            if (!Boolean.TRUE.equals(hasCommunityPermission)) {
                log.warn("用户{}无权限访问社区{}", currentUserId, communityId);
                throw new BusinessException("无权限访问该社区");
            }
            
            log.debug("用户{}权限验证通过，社区ID: {}", currentUserId, communityId);
        } catch (BusinessException e) {
            // 业务异常直接抛出
            throw e;
        } catch (Exception e) {
            log.error("权限验证失败，用户ID: {}, 社区ID: {}, 错误: {}", currentUserId, communityId, e.getMessage());
            // 权限验证失败时，默认拒绝访问，确保安全性
            throw new BusinessException("权限验证失败，请稍后重试");
        }
    }
}
